package com.tegistuff.webos.run.debugger;

import com.intellij.execution.process.OSProcessHandler;
import com.intellij.javascript.debugger.impl.JSDebuggerEditorsProvider;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.tegistuff.webos.run.WebOSRunConfiguration;
import com.tegistuff.webos.run.debugger.breakpoints.WebOSBreakpointWrapper;
import com.tegistuff.webos.run.debugger.breakpoints.WebOSLineBreakpointHandler;
import com.tegistuff.webos.run.debugger.infrastructure.WebOSDebuggerVarRepository;
import org.jetbrains.annotations.NotNull;

/**
 * WebOSDebugProcess.java
 *
 * Copyright (C) 2011-2012 Timo Tegtmeier.
 * All rights reserved.
 */
public class WebOSDebugProcess extends XDebugProcess {

    private WebOSRunConfiguration myRunConfiguration;
    private WebOSDebuggerProxy myDebuggerProxy;
    private WebOSDebuggerVarRepository myVarRepository;
    private WebOSLineBreakpointHandler myLineBreakpointHandler;
    private XBreakpointHandler[] myBreakPointHandlers;
    private OSProcessHandler myLogProcessHandler;
    private boolean myIsClosing;

    public WebOSDebugProcess(@NotNull WebOSRunConfiguration runConfiguration, @NotNull XDebugSession session,
                             WebOSDebuggerProxy debuggerProxy, OSProcessHandler logProcessHandler) {
        super(session);
        myDebuggerProxy = debuggerProxy;
        myDebuggerProxy.setDebugProcess(this);
        myRunConfiguration = runConfiguration;
        myLogProcessHandler = logProcessHandler;

        myLineBreakpointHandler = new WebOSLineBreakpointHandler(runConfiguration, debuggerProxy, session);
        myBreakPointHandlers = new XBreakpointHandler[]{ myLineBreakpointHandler };
        myVarRepository = new WebOSDebuggerVarRepository(this);
    }

    @Override
    public final void sessionInitialized() {
        super.sessionInitialized();
        try {
            myDebuggerProxy.connect();
            if(myLogProcessHandler != null) {
                getSession().getConsoleView().attachToProcess(myLogProcessHandler);
                myLogProcessHandler.startNotify();
            }
        } catch (final Exception e) {
            getSession().reportError(e.getMessage());
            getSession().stop();
        }
    }

    @NotNull
    @Override
    public final XDebuggerEditorsProvider getEditorsProvider() {
        return new JSDebuggerEditorsProvider();
    }

    @Override
    public final void startStepOver() {
        myDebuggerProxy.stepOver();
    }

    @Override
    public final void startStepInto() {
        myDebuggerProxy.stepInto();
    }

    @Override
    public final void startStepOut() {
        myDebuggerProxy.stepOut();
    }

    @Override
    public final void stop() {
        myIsClosing = true;
        if((myLogProcessHandler != null) && myLogProcessHandler.isStartNotified())
            myLogProcessHandler.destroyProcess();
        myDebuggerProxy.stop();
    }

    @Override
    public final void resume() {
        myDebuggerProxy.continueExecution();
    }

    @Override
    public final void runToPosition(@NotNull XSourcePosition position) {

    }

    @Override
    public final XBreakpointHandler<?>[] getBreakpointHandlers() {
        return myBreakPointHandlers;
    }

    public final void registerBreakpoint(WebOSBreakpointWrapper breakpoint) {
        myLineBreakpointHandler.addBreakpointToMap(breakpoint);
    }

    public final void unregisterBreakpoint(WebOSBreakpointWrapper breakpoint) {
        myLineBreakpointHandler.removeBreakpointFromMap(breakpoint);
    }

    @Override
    public final boolean checkCanPerformCommands() {
        return (myDebuggerProxy != null) && myDebuggerProxy.isReady();
    }

    public final WebOSDebuggerProxy getDebuggerProxy() {
        return myDebuggerProxy;
    }

    public final WebOSRunConfiguration getRunConfiguration() {
        return myRunConfiguration;
    }

    public final WebOSLineBreakpointHandler getLineBreakpointHandler() {
        return myLineBreakpointHandler;
    }

    public final WebOSDebuggerVarRepository getVariableRepository() {
        return myVarRepository;
    }

    public final boolean isClosing() {
        return myIsClosing;
    }

    public final void reportInternalError(Exception e) {
        getSession().reportError("Internal debugger error: " + e.getMessage());
    }
}
